class Demo:
    pass


obj = Demo()
print(type(obj))
print(type(Demo))
"""
元类：
所有你写类默认情况下都是type产生的
type产生的类称为元类，即type就是元类,所以继承type的类也就是元类，就拥有了元类的所有方法，就可以覆盖方法
重写生成类的方法
"""


class User(type):
    pass


"""
展示类的三大要素：
1. 类名
2. 父类
3. 类的名称空间
"""
# 下面不同过type产生一个类
class_name = "User"  # 类名
class_bases = (object,)  # 类的父类

res = """
school='oldgirl'
def __init__(self,name):
    self.name=name
def func():
    print(1)
"""
class_attr = {}
exec(res, {}, class_attr)  # 通过exec执行后会创建一个局部的名称空间，这个名称空间就是创建类所需要的
User = type(class_name, class_bases, class_attr)  # 通过调用type创建了一个类
print(User)


# 自定义元类
class MymetaClass(type):
    def __call__(self, *args, **kwargs):
        """
            1. 先创建一个对象的名称空间   __new__
            2. 往改名称空间中丢一堆名字   __init__
            3. 产生好的对象返回出去
        """
        obj = self.__new__(self)
        self.__init__(obj, *args, **kwargs)
        return obj
        # return super().__call__(self, *args, **kwargs)  # 可以直接调用父类的call方法


class Demo(metaclass=MymetaClass):  # 指定demo的元类
    pass


obj = Demo()  # 实际上Demo+括号就是调用的是元类中的__call__方法
print(obj)

